package cn.iocoder.an.module.mold.service.repairaccount;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.an.module.mold.controller.admin.upkeeptobe.vo.UpkeepTobeDispatchVO;
import cn.iocoder.an.module.mold.dal.dataobject.account.AccountDO;
import cn.iocoder.an.module.mold.dal.dataobject.rechecktobe.RecheckTobeDO;
import cn.iocoder.an.module.mold.dal.dataobject.repairjob.RepairJobDO;
import cn.iocoder.an.module.mold.dal.dataobject.repairstatics.RepairStaticsDO;
import cn.iocoder.an.module.mold.dal.dataobject.upkeepstatics.UpkeepStaticsDO;
import cn.iocoder.an.module.mold.dal.dataobject.upkeeptask.UpkeepTaskDO;
import cn.iocoder.an.module.mold.dal.dataobject.upkeeptobe.UpkeepTobeDO;
import cn.iocoder.an.module.mold.dal.mysql.account.AccountMapper;
import cn.iocoder.an.module.mold.dal.mysql.repairjob.RepairJobMapper;
import cn.iocoder.an.module.mold.dal.mysql.repairstatics.RepairStaticsMapper;
import cn.iocoder.an.module.mold.dal.mysql.upkeeptask.UpkeepTaskMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

import cn.iocoder.an.module.mold.controller.admin.repairaccount.vo.*;
import cn.iocoder.an.module.mold.dal.dataobject.repairaccount.RepairAccountDO;
import cn.iocoder.an.framework.common.pojo.PageResult;
import cn.iocoder.an.framework.common.pojo.PageParam;
import cn.iocoder.an.framework.common.util.object.BeanUtils;

import cn.iocoder.an.module.mold.dal.mysql.repairaccount.RepairAccountMapper;

import static cn.iocoder.an.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.an.module.mold.enums.ErrorCodeConstants.*;

/**
 * 模具维修申请 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class RepairAccountServiceImpl implements RepairAccountService {

    @Resource
    private RepairAccountMapper repairAccountMapper;

    @Resource
    private AccountMapper accountMapper;

    @Resource
    private RepairJobMapper repairJobMapper;

    @Resource
    private RepairStaticsMapper repairStaticsMapper;


    @Override
    public Long createRepairAccount(RepairAccountSaveReqVO createReqVO) {
        BeanUtils.toBean(createReqVO, RepairAccountDO.class);
        if (existsByAccountId(createReqVO.getAccountId())) {
            throw exception(REPAIR_MOLD_ALREADY_EXISTS);
        }
        createReqVO.setCode(UUID.randomUUID().toString());
        //申请时间去创建时间
        createReqVO.setApplicationTime(LocalDateTime.now());
        createReqVO.setStatus(1);
        RepairAccountDO repairAccount = BeanUtils.toBean(createReqVO, RepairAccountDO.class);
        repairAccountMapper.insert(repairAccount);
        return repairAccount.getId();
    }

    @Override
    public void updateRepairAccount(RepairAccountSaveReqVO updateReqVO) {
        // 校验存在
        validateRepairAccountExists(updateReqVO.getId());
        // 更新
        RepairAccountDO updateObj = BeanUtils.toBean(updateReqVO, RepairAccountDO.class);
        repairAccountMapper.updateById(updateObj);
    }

    @Override
    public void deleteRepairAccount(Long id) {
        // 校验存在
        validateRepairAccountExists(id);
        // 删除
        repairAccountMapper.deleteById(id);

        // 物理删除（真删除）
        //  repairAccountMapper.forceDeleteById(id);
    }

    @Override
    public void deleteRepairAccountListByIds(List<Long> ids) {
        // 删除
        repairAccountMapper.deleteByIds(ids);
    }


    private void validateRepairAccountExists(Long id) {
        if (repairAccountMapper.selectById(id) == null) {
            throw exception(REPAIR_ACCOUNT_NOT_EXISTS);
        }
    }


    @Override
    public RepairAccountDO getRepairAccount(Long id) {
        return repairAccountMapper.selectById(id);
    }

    @Override
    public PageResult<RepairAccountDO> getRepairAccountPage(RepairAccountPageReqVO pageReqVO) {
        return repairAccountMapper.selectPage(pageReqVO);
    }

    @Override
    public Boolean dispatch(RepairAccountDispatchVO dispatch) {
        LocalDateTime now = LocalDateTime.now();
        //待保养任务Id
        long repairAccountId = dispatch.getId();
        Long assigneerId = dispatch.getAssigneerId();

        RepairAccountDO repairAccount = repairAccountMapper.selectById(repairAccountId);

        RepairJobDO repairJob = new RepairJobDO();
        repairJob.setCode(UUID.randomUUID().toString());
        repairJob.setAccountId(repairAccount.getAccountId());
        repairJob.setAssigneerId(assigneerId);
        //维修分类
        repairJob.setDepartId(repairAccount.getDepartId());
        repairJob.setFaultId(repairAccount.getFaultId());
        repairJob.setFaultDescription(repairAccount.getFaultDescription());
        repairJob.setApplicantId(repairAccount.getApplicantId());
        repairJob.setApplicationTime(now);
        repairJob.setStatus(2);
        //创建task
        repairJobMapper.insert(repairJob);

        //更新
        repairAccount.setJobId(repairJob.getId());
        repairAccount.setStatus(2);
        repairAccountMapper.updateById(repairAccount);
        return true;
    }


    public Boolean cancelDispatch(Long id) {
        RepairAccountDO repairaccount = repairAccountMapper.selectById(id);
        if (repairaccount.getStatus() > 2) {
            throw exception(REPAIR_ACCOUNT_ALREADY_EXISTS);
        }
        //删除任务
        repairJobMapper.deleteById(repairaccount.getJobId());
        //修改待保养任务状态
        repairaccount.setJobId(null);
        repairaccount.setStatus(1);
        //更新
        repairAccountMapper.updateById(repairaccount);
        return true;
    }


    public Boolean audit(RepairAccountAuditVO audit) {
        RepairJobDO job = repairJobMapper.selectById(audit.getId());
        RepairAccountDO repairAccountDO = repairAccountMapper.selectOne(new LambdaQueryWrapper<RepairAccountDO>().eq(RepairAccountDO::getJobId, job.getId()));
        job.setActualStartTime(audit.getActualStartTime());
        job.setActualEndTime(audit.getActualEndTime());
        job.setActualExecutionDuration(audit.getActualExecutionDuration());
        job.setActualExecutionDuration(audit.getActualExecutionDuration());
        job.setRepairCategoryId(audit.getRepairCategoryId());
        job.setRepairerIds(audit.getRepairerIds());
        job.setRepairerIds(audit.getRepairerIds());
        job.setFaultAnalysis(audit.getFaultAnalysis());
        job.setRepairItems(audit.getRepairItems());
        job.setRepairCost(audit.getRepairCost());

        job.setStatus(6);
        repairJobMapper.updateById(job);

        repairAccountDO.setStatus(6);
        repairAccountMapper.updateById(repairAccountDO);

        //todo:后续需要在这里增加寿命相关的信息

        //增加统计信息

        RepairStaticsDO staticsDO = new RepairStaticsDO();
        staticsDO.setAccountId(repairAccountDO.getAccountId());
        //获取原统计记录
        if (repairStaticsMapper.selectCount(new LambdaQueryWrapper<RepairStaticsDO>().eq(RepairStaticsDO::getAccountId, repairAccountDO.getId())) > 0) {
            staticsDO = repairStaticsMapper.selectOne(new LambdaQueryWrapper<RepairStaticsDO>().eq(RepairStaticsDO::getAccountId, repairAccountDO.getId()));
            staticsDO.setRepairCounts(staticsDO.getRepairCounts() + 1);
            staticsDO.setRepairManHours(staticsDO.getRepairManHours() + job.getActualExecutionDuration());
        } else {
            staticsDO.setRepairCounts(1L);
            staticsDO.setRepairManHours(job.getActualExecutionDuration());
        }
        staticsDO.setOuterRepairCounts(1L);
        staticsDO.setOuterRepairManHours(job.getActualExecutionDuration());
        repairStaticsMapper.insertOrUpdate(staticsDO);
        return true;
    }


    public Boolean existsByAccountId(Long accountId) {
        // 使用 QueryWrapper 进行查询
        QueryWrapper<RepairAccountDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_id", accountId);
        return repairAccountMapper.selectCount(queryWrapper) > 0;
    }

}